package shining365.programmableweb.data.app;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.Map.Entry;

import javax.xml.bind.JAXBException;

import org.junit.Test;

public class HistoryOfApiActiveness {
	
	@Test
	public void computeActivenessHistory() throws IOException, ParseException, JAXBException {
		final int step = 7;
		Calendar calendar = 
			new GregorianCalendar(2005, Calendar.SEPTEMBER, 18, 0, 0, 0);
		calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
		
		Map<String, List<Double>> api2activenesses = 
			new HashMap<String, List<Double>>();

		Calendar endCalendar = 
			new GregorianCalendar(2009, Calendar.SEPTEMBER, 20, 0, 0, 0);
		endCalendar.setTimeZone(TimeZone.getTimeZone("UTC"));
		Date endDate = endCalendar.getTime();
		while (true) {
			Date date = calendar.getTime();
			if (date.compareTo(endDate) > 0) {
				break;
			}
			
			Date newDate = calendar.getTime();
			calendar.add(Calendar.DAY_OF_MONTH, -1 * DELTA);
			Date oldDate = calendar.getTime();
			calendar.add(Calendar.DAY_OF_MONTH, DELTA);
			
			ApiActiveness ac = new ApiActiveness(oldDate, newDate);
			Map<String, Double> api2activeness = ac.getApiActiveness();
			for (Entry<String, Double> e : api2activeness.entrySet()) {
				List<Double> centralities = api2activenesses.get(e.getKey());
				if (centralities == null) {
					centralities = new ArrayList<Double>();
				}
				centralities.add(e.getValue());
				api2activenesses.put(e.getKey(), centralities);
			}
			
			calendar.add(Calendar.DAY_OF_MONTH, step);
		}
		
		for (Entry<String, List<Double>> entry : api2activenesses.entrySet()) {
			System.out.println(entry.getKey());
			List<Double> activenesses = entry.getValue();
			int week = LATEST_WEEK - activenesses.size();
			for (double d : activenesses) {
				System.out.printf("%d\t%f\n", ++week, d);
			}
			System.out.println();
		}
	}
	
	@Test
	public void computeActivenessHistoryTop10Sum() throws IOException, ParseException, JAXBException {
		final int step = 7;
		Calendar calendar = 
			new GregorianCalendar(2005, Calendar.SEPTEMBER, 18, 0, 0, 0);
		calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
		
		final int N = 10;
		
		Calendar endCalendar = 
			new GregorianCalendar(2009, Calendar.AUGUST, 27, 0, 0, 0);
		endCalendar.setTimeZone(TimeZone.getTimeZone("UTC"));
		Date endDate = endCalendar.getTime();
		while (true) {
			Date date = calendar.getTime();
			if (date.compareTo(endDate) > 0) {
				break;
			}
			
			Date newDate = calendar.getTime();
			calendar.add(Calendar.DAY_OF_MONTH, -1 * DELTA);
			Date oldDate = calendar.getTime();
			calendar.add(Calendar.DAY_OF_MONTH, DELTA);
			
			ApiActiveness ac = new ApiActiveness(oldDate, newDate);
			Map<String, Double> api2activeness = ac.getApiActiveness();
			List<Double> activenesses = new ArrayList<Double>();
			for (Entry<String, Double> e : api2activeness.entrySet()) {
				activenesses.add(e.getValue());
			}
			Collections.sort(activenesses, Collections.reverseOrder());
			double sum = 0;
			for (int i = 0; i < N; i++) {
				sum += activenesses.get(i);
			}
			System.out.println(sum);
			
			calendar.add(Calendar.DAY_OF_MONTH, step);
		}
		
	}
	
	private static final int DELTA = 7 * 13;
	private static final int LATEST_WEEK = 210;
}
